﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
using BarberShop.Properties;

namespace BarberShop
{
    partial class MainForm
    {
        private void SetDefaultInfoPanel()
        {
            Log.Info("Setting default info panel");
            nameSurnmaeLabel.Text = Resources.DefaultNameSurname;
            mainPhoneLabel.Text = Resources.DefaultPhoneNumber;
            additionalPhoneLabel.Text = Resources.DefaultPhoneNumber;
            notesTextBox.Text = "";
            UpdateOperationsPanel(int.MaxValue);
            operationSummaryLabel.Text = "";
            editClientLinkLabel.Enabled = false;
        }


        private void TryToSelectFistClient()
        {
            if (clientsDataGridView.Rows.Count == 0)
            {
                Log.Warn("Unable to select first client, clientsDataGridView.Rows.Count == 0");
                SetDefaultInfoPanel();
                return;
            }

            DataGridViewRow firstRow = clientsDataGridView.Rows[0];
            firstRow.Selected = true;
            UpdateClietInfoPanel(GetSelectedClientId());
        }

        private void UpdateClietInfoPanel(int clientId)
        {
            Log.Info("Updating client info panel for client id = " + clientId);
            dbDataSet.ClientsRow selectedClient = dbDataSet.Clients.FindByClientId(clientId);

            if (selectedClient == null)
            {
                SetDefaultInfoPanel();
                return;
            }

            nameSurnmaeLabel.Text = selectedClient.Name + " " + selectedClient.Surname;
            mainPhoneLabel.Text = selectedClient.PrimaryPhone;
            additionalPhoneLabel.Text = (selectedClient.SecondaryPhone == "")
                                            ? Resources.DefaultPhoneNumber
                                            : selectedClient.SecondaryPhone;
            notesTextBox.Text = selectedClient.Note;
            editClientLinkLabel.Enabled = true;

            UpdateOperationsPanel(clientId);
        }

        private void UpdateOperationsPanel(int clientId)
        {
            Log.Info("Updating operations info panel for client id = " + clientId);
            var operationsDataView = new DataView(dbDataSet.Operations);
            operationsDataView.RowFilter = dbDataSet.Operations.ClientRefColumn.ColumnName + " = " + clientId;
            operationsDataView.Sort = dbDataSet.Operations.DateColumn.ColumnName;

            DataTable humanReadableDt = CreateHumanReadableDataTable(operationsDataView);

            int numberOfOperations = humanReadableDt.Rows.Count;
            if (numberOfOperations != 0)
            {
                object lastVist = humanReadableDt.Rows[numberOfOperations - 1]["Дата"];
                operationSummaryLabel.Text = String.Format(Resources.OperationsSummaryPatern, numberOfOperations,
                                                           lastVist);
                removeServiseButton.Enabled = true;
            }
            else
            {
                operationSummaryLabel.Text = Resources.OperationsSummaryNoOperations;
                removeServiseButton.Enabled = false;
            }

            operationsDataGridView.DataSource = humanReadableDt;
        }

        private DataTable CreateHumanReadableDataTable(DataView dataView)
        {
            Log.Info("Creating human readable operations table");
            var resultTable = new DataTable("humanReadableOperations");

            resultTable.Columns.Add("Ід операції", typeof (String));
            resultTable.Columns.Add("Послуга", typeof (String));
            resultTable.Columns.Add("Вартість", typeof (String));
            resultTable.Columns.Add("Дата", typeof (String));

            DataTable filtredRows = dataView.ToTable("filtred");

            foreach (DataRow row in filtredRows.Rows)
            {
                string operationId = row[dbDataSet.Operations.OperationIdColumn.ColumnName].ToString();

                string serviceRef = row[dbDataSet.Operations.ServiceRefColumn.ColumnName].ToString();
                int serviceRefI = int.Parse(serviceRef);
                dbDataSet.ServicesRow service = dbDataSet.Services.FindByServiceId(serviceRefI);

                string price = row[dbDataSet.Operations.PriceColumn.ColumnName].ToString();

                string date = row[dbDataSet.Operations.DateColumn.ColumnName].ToString();
                DateTime dateTime = DateTime.Parse(date);

                resultTable.Rows.Add(operationId, service.Name, price, String.Format("{0: d MMMMM, yyyy}", dateTime));
            }
            return resultTable;
        }

        private int GetSelectedClientId()
        {
            DataGridViewRow selectedRow = clientsDataGridView.CurrentRow;
            return selectedRow != null ? int.Parse(selectedRow.Cells[0].Value.ToString()) : 0;
        }

        private int GetSelectedOperationId()
        {
            DataGridViewRow selectedRow = operationsDataGridView.CurrentRow;
            return selectedRow != null ? int.Parse(selectedRow.Cells[0].Value.ToString()) : 0;
        }

        private void EditClient(int clientId)
        {
            Log.Info("Starting editing client with id = " + clientId);
            dbDataSet.ClientsRow clientRow = dbDataSet.Clients.FindByClientId(clientId);

            if (clientRow == null)
            {
                Log.Warn("Unable to start editing, client with id = " + clientId + " not found");
                return;
            }

            var adf = new AddClientForm(clientRow.Name, clientRow.Surname, clientRow.PrimaryPhone,
                                        clientRow.SecondaryPhone, clientRow.Note);
            if (adf.ShowDialog() == DialogResult.OK)
            {
                clientRow.BeginEdit();
                clientRow.Name = adf.ClientName;
                clientRow.Surname = adf.ClientSurname;
                clientRow.PrimaryPhone = adf.PrimaryPhone;
                clientRow.SecondaryPhone = adf.SecondaryPhone;
                clientRow.Note = adf.Notes;
                clientRow.EndEdit();

                UpdateClientsTable();

                UpdateClietInfoPanel(clientId);
            }
        }

        private void UpdateDbStatisticsLable()
        {
            dbStatsToolStripStatusLabel.Text = String.Format(Resources.DbStatisticsSummaryPattern,
                                                             dbDataSet.Clients.Rows.Count,
                                                             dbDataSet.Operations.Rows.Count,
                                                             dbDataSet.Services.Rows.Count);
        }

        private void UpdateFilter()
        {
            Log.Info("Filtring started");
            var result = new List<dbDataSet.ClientsRow>();
            dbDataSet.ClientsRow[] clientsFiltredByNameAndPhone = GetClientsFiltredByNameAndPhone();

            if (enableOperationTypeFilterCheckBox.Checked && providedServisesComboBox.SelectedValue != null)
            {
                IEnumerable<string> clientIds = GetClientIdsFiltredByProvidedServices();

                foreach (string clientId in clientIds)
                {
                    foreach (dbDataSet.ClientsRow row in clientsFiltredByNameAndPhone)
                    {
                        if (clientId.Equals(row.ClientId.ToString()))
                        {
                            result.Add(row);
                        }
                    }
                }
            }
            else
            {
                result.AddRange(clientsFiltredByNameAndPhone);
            }
            Log.Info("Filtring finished, " + result.Count + " clients found");

            clientsDataGridView.DataSource = result.ToArray();
            removeClientButton.Enabled = result.Count != 0;
            addOperationButton.Enabled = result.Count != 0;


            TryToSelectFistClient();
            clearFilterLinkLabel.Enabled = true;
        }

        private IEnumerable<string> GetClientIdsFiltredByProvidedServices()
        {
            Log.Info("Filtring clients by provided services started");
            var clieneIds = new List<string>();

            dbDataSet.OperationsRow[] selectedOperations;

            if (providedServisesComboBox.SelectedItem != null)
            {
                string query = dbDataSet.Operations.ServiceRefColumn.ColumnName + " = '" +
                               ((DataRowView) providedServisesComboBox.SelectedItem)[
                                   dbDataSet.Services.ServiceIdColumn.ColumnName] + "'";
                selectedOperations = (dbDataSet.OperationsRow[]) dbDataSet.Operations.Select(query);
            }
            else
            {
                selectedOperations = (dbDataSet.OperationsRow[]) dbDataSet.Operations.Select();
            }

            foreach (dbDataSet.OperationsRow row in selectedOperations)
            {
                string clientId = row.ClientRef.ToString();
                if (!clieneIds.Contains(clientId))
                {
                    clieneIds.Add(clientId);
                }
            }

            Log.Info("Filtring by by provided services finished, " + clieneIds.Count + " clients found");

            return clieneIds;
        }

        private dbDataSet.ClientsRow[] GetClientsFiltredByNameAndPhone()
        {
            Log.Info("Filtring clients by name and phone started");
            string query = "";
            if (!nameFilterTextBox.Text.Trim().Equals(""))
            {
                query += dbDataSet.Clients.NameColumn.ColumnName + " LIKE '%" + nameFilterTextBox.Text.Trim() + "%'";
            }
            if (!phoneFilterTextBox.Text.Trim().Equals(""))
            {
                query += query.Equals("") ? "" : " AND ";
                query += dbDataSet.Clients.PrimaryPhoneColumn.ColumnName + " LIKE '%" + phoneFilterTextBox.Text.Trim() +
                         "%' OR " + dbDataSet.Clients.SecondaryPhoneColumn.ColumnName + " LIKE '%" +
                         phoneFilterTextBox.Text.Trim() +
                         "%'";
            }

            var dataRows = (dbDataSet.ClientsRow[]) dbDataSet.Clients.Select(query);
            Log.Info("Filtring by by name and phone finished, " + dataRows.Length + " clients found");
            return dataRows;
        }

        private void ClearFilter()
        {
            clientsDataGridView.DataSource = clientsBindingSource;
            nameFilterTextBox.Text = "";
            phoneFilterTextBox.Text = "";
            clearFilterLinkLabel.Enabled = false;
            TryToSelectFistClient();
            removeClientButton.Enabled = clientsDataGridView.Rows.Count > 0;
            addOperationButton.Enabled = clientsDataGridView.Rows.Count > 0;
        }

        private void OpenServicesManager()
        {
            new ServiceManagerForm(this).ShowDialog();
        }
    }
}